package com.hksj.data.service;

import com.alibaba.fastjson.JSONObject;
import com.hksj.data.entity.BaseDeviceProperty;
import com.hksj.data.mapper.DevicePropertyMapper;
import com.hksj.data.vo.DefinedDeviceMetadataVO;
import com.hksj.data.vo.DeviceMetadataVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zengke
 * @version 1.0
 * @see DevicePropertyService
 * @since 2025/08/15 10:46
 */

@Service
public class DevicePropertyService {

    @Autowired
    private DevicePropertyMapper devicePropertyMapper;

    /**
     * 批量封装设备属性信息
     * @param list 设备属性列表
     */
    public void wrap(List<? extends BaseDeviceProperty> list){

        //判断设备属性列表是否为空
        if (!ObjectUtils.isEmpty(list)){

            //不为空 获取设备实体id列表
            List<String> deviceInstanceIdList = list.stream().map(BaseDeviceProperty::getDeviceId).collect(Collectors.toList());

            //通过设备实体id列表 查询当前设备的定义的物模型信息(物模型属性来源:继承自产品的、自身独有的)
            List<DefinedDeviceMetadataVO> definedDeviceMetadataList = devicePropertyMapper.queryDefinedDeviceMetadataList(deviceInstanceIdList);

            //判断设备定义的物模型列表是否为空
            if (!ObjectUtils.isEmpty(definedDeviceMetadataList)){

                //当前设备定义的物模型列表不为空、将设备定义物模型和产品定义物模型进行合并、然后转换为物模型对象、最后收集为一个新的物模型列表
                Map<String, Map<String, DeviceMetadataVO.Properties>> deviceMetadataMap = definedDeviceMetadataList.stream().collect(Collectors.toMap(
                        DefinedDeviceMetadataVO::getDeviceInstanceId,
                        definedDeviceMetadataVO -> {
                            DeviceMetadataVO deviceMetadataVO = mergeMetadata(definedDeviceMetadataVO.getDeriveMetadata(), definedDeviceMetadataVO.getMetadata());
                            return deviceMetadataVO.getProperties().stream().collect(Collectors.toMap(DeviceMetadataVO.Properties::getId, Function.identity()));
                        }));

                //获取设备信息集合
                Map<String, DefinedDeviceMetadataVO> deviceMap = definedDeviceMetadataList.stream().collect(Collectors.toMap(DefinedDeviceMetadataVO::getDeviceInstanceId, Function.identity()));

                //设置每个设备属性列表对应的属性信息
                list.forEach(deviceProperty -> {

                    //获取设备信息
                    DefinedDeviceMetadataVO definedDeviceMetadataVO = deviceMap.get(deviceProperty.getDeviceId());

                    //获取当前设备对应的物模型属性集合
                    Map<String, DeviceMetadataVO.Properties> propertiesMap = deviceMetadataMap.get(deviceProperty.getDeviceId());

                    //获取物模型属性代码对应的物模型属性对象
                    DeviceMetadataVO.Properties property = propertiesMap.get(deviceProperty.getProperty());

                    //判断物模型属性对象是否为空
                    if (!ObjectUtils.isEmpty(property)){

                        //当物模型属性对象不为空时 设置物模型属性的其他信息
                        //设置物模型属性的其他信息
                        deviceProperty.setPropertyName(property.getName()); //名称
                        deviceProperty.setType(property.getValueType().getType()); //数据类型
                        deviceProperty.setUnit(property.getValueType().getUnit()); //单位

                        //设置设备的产品id
                        deviceProperty.setProductId(definedDeviceMetadataVO == null ? null : definedDeviceMetadataVO.getProductId());
                    }

                });
            }
        }
    }

    /**
     * 合并物模型
     * @param deriveMetadata 设备定义物模型
     * @param metadata 产品定义物模型
     * @return 合并后的物模型
     */
    public DeviceMetadataVO mergeMetadata(String deriveMetadata, String metadata){

        //合并后的物模型
        DeviceMetadataVO mergedMetadata = new DeviceMetadataVO();

        //获取合并后的属性列表
        List<DeviceMetadataVO.Properties> mergedProperties = mergedMetadata.getProperties();

        //获取合并后的功能列表
        List<DeviceMetadataVO.Functions> mergedFunctions = mergedMetadata.getFunctions();

        //获取合并后的事件列表
        List<DeviceMetadataVO.Events> mergedEvents = mergedMetadata.getEvents();

        //获取合并后的标签列表
        List<DeviceMetadataVO.Tags> mergedTags = mergedMetadata.getTags();

        //判断设备定义物模型是否为空
        if (StringUtils.hasText(deriveMetadata)){

            //不为空、进行解析
            DeviceMetadataVO deviceMetadataVO = JSONObject.parseObject(deriveMetadata, DeviceMetadataVO.class);

            //将设备定义物模型属性列表全部添加到合并后的物模型中
            mergedProperties.addAll(deviceMetadataVO.getProperties());

            //将设备定义物模型功能列表全部添加到合并后的物模型中
            mergedFunctions.addAll(deviceMetadataVO.getFunctions());

            //将设备定义物模型事件列表全部添加到合并后的物模型中
            mergedEvents.addAll(deviceMetadataVO.getEvents());

            //将设备定义物模型标签列表全部添加到合并后的物模型中
            mergedTags.addAll(deviceMetadataVO.getTags());

        }

        //判断产品定义物模型是否为空
        if (StringUtils.hasText(metadata)){

            //不为空、进行解析
            DeviceMetadataVO deviceMetadataVO = JSONObject.parseObject(metadata, DeviceMetadataVO.class);

            //将产品定义物模型属性列表全部添加到合并后的物模型中
            mergedProperties.addAll(deviceMetadataVO.getProperties());

            //将产品定义物模型功能列表全部添加到合并后的物模型中
            mergedFunctions.addAll(deviceMetadataVO.getFunctions());

            //将产品定义物模型事件列表全部添加到合并后的物模型中
            mergedEvents.addAll(deviceMetadataVO.getEvents());

            //将产品定义物模型标签列表全部添加到合并后的物模型中
            mergedTags.addAll(deviceMetadataVO.getTags());
        }

        //返回合并后的物模型
        return mergedMetadata;
    }
}
